#include <fstream>
#include<vector>
#include<string.h>
#include "dbHead.h"

//index management
#include<time.h>
#include"b_plus_tree.h"
#define INDEX_DAT "b_plus_tree_index.dat"

using namespace std;

//supplier表映射类
class Supplier{
public:
    int s_suppkey;
    char s_name[25];
    string s_address;//varchar(40)
    int s_nationkey;
    char s_phone[15];
    float s_acctbal;
    string s_comment;//varchar(101)
};

//把内存中的所有数据写入到磁盘中
int sysUpdate(struct DBMSHeader *header){
    rewind(header->fpdesc);
    fwrite(&(header->desc), sizeof(struct SysDesc), 1, header->fpdesc);

    rewind(header->fpdesc);
    fseek(header->fpdesc, header->desc.bitMapAddr, SEEK_SET);
    fwrite(header->freeSpace_bitMap, sizeof(char), header->desc.bitMapSize, header->fpdesc);

    for(int i=0; i<SIZE_BUFF; i++) {
        if(header->buffer.map[i].isEdited == true) {
            rewind(header->fpdesc);
            fseek(header->fpdesc, header->desc.dataAddr + SIZE_PER_PAGE*header->buffer.map[i].pageNo, SEEK_SET);
            fwrite(header->buffer.data[i], sizeof(char), SIZE_PER_PAGE, header->fpdesc);
            header->buffer.map[i].isEdited = false;
        }
    }
    return 0;
}

void insertRecord(struct DBMSHeader *header, int fid)
{
    ifstream in;
    in.open("/home/mark/usr/data/supplier.tbl");
    string recordStr;
    Supplier suppiler;
    vector<string> v;
    if (!in.is_open()) {
        cout<<"Error"<<endl;
    }else{
        while(getline(in, recordStr))
        {
            //getline(in, recordStr);
            splitString(recordStr, v,"|");
            writeFile(header, fid, (int)strlen(recordStr.c_str()), recordStr.c_str());
            //cout<<recordStr<<endl;
            //for(vector<string>::size_type i = 0; i != v.size(); ++i)
            //cout << v[i] << endl;
            suppiler.s_suppkey=atoi(v[0].c_str());
            strcpy(suppiler.s_name, v[1].c_str());
            suppiler.s_address=v[2];
            suppiler.s_nationkey=atoi(v[3].c_str());
            strcpy(suppiler.s_phone, v[4].c_str());
            suppiler.s_acctbal=atof(v[5].c_str());
            suppiler.s_comment=v[6];
            //输出测试
            //cout<<suppiler.s_suppkey<<endl;
            //cout<<suppiler.s_name<<endl;
            //cout<<suppiler.s_address<<endl;
            //cout<<suppiler.s_nationkey<<endl;
            //cout<<suppiler.s_phone<<endl;
            //cout<<suppiler.s_acctbal<<endl;
            //cout<<suppiler.s_comment<<endl;
            //size_t lengthx = strlen(recordStr.c_str());
            //cout<<strlen(recordStr.c_str())<<endl;
        }
    }
    in.close();
    char des[1000];
    readFile(header,fid,des);
    sysUpdate(header);
    showStatus(header);
}


int main(int argc, const char * argv[]) {

//test1  storage manaegment
//    struct DBMSHeader header; //
//    char dbfile[10] = "dbms.mat";
//    initDatabase(&header,dbfile);
//    showStatus(&header);
//    int fid = createFile(&header, DATA_FILE, 1);
//    cout<<"创建文件"<<fid<<"成功!"<<endl;
//   insertRecord(&header, fid);
//    //deleteFile(&header, 0);
//    //recyAllPage(&header);
//    //showStatus(&header);
//    fclose(header.fpdesc);
//    free(header.freeSpace_bitMap);

    //test2 indexManagement




	FILE *fp;
	int key_num = 20;
	Record record_insert;
 int x = 1;
    int y = 0;
		fp=fopen(INDEX_DAT,"rb+");
	if (fp == NULL){
		printf("索引文件不存在，重新建立索引....\n");
		FILE *fp_create;
		fp_create=fopen (INDEX_DAT, "wb");
		fclose(fp_create);
		fp=fopen(INDEX_DAT, "rb+");
		if (fp == NULL){
			printf("fopen error!\n");
			exit(0);
		}
	}
    while (0 != x)
    {
        printf("\n\n");
        printf("    *******************************************************************\n");
        printf("    *           欢迎进入B+树演示程序，请选择相应功能。                *\n");
        printf("    *           1。建立一棵B+树；                                     *\n");
        printf("    *           2。在B+树中查找一个数；                               *\n");
        printf("    *           3。在B+树中插入一个数；                               *\n");
        printf("    *           4。在B+树中删除一个数；                               *\n");
		printf("    *           5。打印B+树；										  *\n");
        printf("    *           0。退出程序；                                         *\n");
        printf("    *******************************************************************\n");
        printf("\n    您的选择是：");


        scanf("%d", &x);
		int k = 0;
		int w=0;
		Node node;
        switch (x)
        {
        case 1:

			rewind(fp);
			for (k= 0; k<=8; k++)
			{
				record_insert.key = k;
				record_insert.pos = k* 2;
				insert(fp, record_insert);
			}
			rewind(fp);

			for(w=0;w<node.count;w++)
			{
				printf("%d ,",node.pair[w].key);
			}
           break;

        case 2:
			int c;
			printf("input the key you search");
			scanf("%d",&c);
           	search(fp,c);
			printf("search succeed");
			break;

        case 3:

			int b;
			printf("input the key you want insert");
			scanf("%d",&b);
			record_insert.key = b;
			record_insert.pos = b* 2;
           	insert(fp,record_insert);
			printf("insert succeed");

            break;

        case 4:

			int a;
			printf("input the key you want delet");
			scanf("%d",&a);
           	del(fp,a);
			printf("delet succeed");
            break;
		case 5:
			Node node;
			getRoot(fp, node);
			int rootOffSet;
			Node rootNode;
			rewind(fp);
			fread(&rootOffSet, 1, sizeof(rootOffSet), fp);
			fseek(fp, rootOffSet, SEEK_SET);
			fread(&node, 1, sizeof(node), fp);
			showTree(fp,node);
			break;

        case 0:
         fclose(fp);
            return 0;
            break;

        default:
            break;
        }
    }

    return 0;
}

